package org.anderground.app.storage.global;

import java.io.IOException;

import org.anderground.app.PreconditionActivityHelper;
import org.anderground.app.R;
import org.anderground.app.UserTask;
import org.anderground.app.storage.AppStorage;
import org.anderground.app.storage.cache.CacheStorage;
import org.anderground.app.storage.db.DbStorage;
import org.anderground.app.storage.global.GlobalStorageProxy.OnDoubleProgressCallback;
import org.anderground.app.storage.xml.FileXmlStorage;
import org.anderground.app.storage.xml.ResourceXmlStorage;
import org.anderground.core.Logger;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;

/**
 * @author Eldar Abusalimov
 */
public class StorageSetupActivity extends Activity {

	private static final String ACTION_SETUP = "org.anderground.app.content.ResourcesActivity.ACTION_SETUP";

	/**
	 * It checks if the app has been set up after its installation. If so,
	 * returns true. If not, starts an activity to do initial setup and returns
	 * false. If this function returns false the caller should immediately
	 * return from its onCreate method. The calling activity will later be
	 * restarted (using a copy of its original intent) once the application
	 * setup completes.
	 * 
	 * @param activity
	 *            The calling activity.
	 * @return true if the application has already been set up successfully, or
	 *         false the application has been run for the first time and needs
	 *         to be set up.
	 */
	public static boolean ensureSetup(Activity activity) {
		if (tryQuickSetup(activity)) {
			return true;
		}
		Intent intent = PreconditionActivityHelper.createPreconditionIntent(
				activity, StorageSetupActivity.class);
		intent.setAction(ACTION_SETUP);
		PreconditionActivityHelper.startPreconditionActivityAndFinish(activity,
				intent);
		return false;
	}

	/**
	 * Tries to setup the {@link GlobalStorageProxy} with instances of
	 * {@link CacheStorage} and {@link DbStorage}.
	 * 
	 * @param context
	 * @return
	 */
	private static boolean tryQuickSetup(Context context) {
		final AppStorage[] quickStorages = new AppStorage[] {
				CacheStorage.getInstance(), DbStorage.getInstance(context) };
		boolean ok = GlobalStorageProxy
				.tryConfiguratingDummyInstance(quickStorages);
		if (ok) {
			return tryFullSetup(context, null);
		}
		return ok;
	}

	/**
	 * @param context
	 * @param callback
	 * @return
	 */
	private static boolean tryFullSetup(Context context,
			OnDoubleProgressCallback callback) {
		final AppStorage[] storages = new AppStorage[] {
				CacheStorage.getInstance(), DbStorage.getInstance(context),
				ResourceXmlStorage.getInstance(context),
				FileXmlStorage.getInstance(context) };
		try {
			// TODO remove dumpConfig() invocation
			GlobalStorageProxy.createAndConfigureInstance(storages, callback)
					.dumpConfig();
			return true;
		} catch (IOException e) {
			Logger.e("GlobalStorageProxy configurating failed", e);
			return false;
		}
	}

	private ProgressBar progressBar;
	private TextView textView;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Intent intent = getIntent();
		String action = intent.getAction();
		if (!ACTION_SETUP.equals(action)) {
			finish();
		}

		setContentView(R.layout.setup);
		progressBar = (ProgressBar) findViewById(R.id.setup_progress);
		textView = (TextView) findViewById(R.id.setup_text);
		new FullSetupTask().execute();
	}

	/**
	 * @author Eldar Abusalimov (eldar.abusalimov@gmail.com)
	 */
	private class FullSetupTask extends UserTask<Void, String, Boolean> {

		@Override
		protected Boolean doInBackground(Void... params)
				throws FailureException {
			return tryFullSetup(StorageSetupActivity.this,
					new OnDoubleProgressCallback() {

						@Override
						public void onProgress(int progress, int max,
								String message) {
							onProgress(message);
							progressBar.setMax(max);
							progressBar.setProgress(progress);
						}

						@Override
						public void onSecondaryProgress(int secondaryProgress,
								int max, String message) {
							onProgress(message);
							progressBar.setMax(max);
							progressBar.setSecondaryProgress(secondaryProgress);

						}

						@Override
						public void onProgress(String message) {
							if (message != null) {
								publishProgress(message);
							}
						}

					});
		}

		@Override
		protected void onPostExecute(Boolean result) {
			progressBar.setProgress(progressBar.getMax());
			progressBar.setSecondaryProgress(progressBar.getMax());
			PreconditionActivityHelper
					.startOriginalActivityAndFinish(StorageSetupActivity.this);
		}

		@Override
		protected void onPreExecute() {
			progressBar.setProgress(0);
			progressBar.setSecondaryProgress(0);
		}

		@Override
		protected void onProgress(String... values) {
			if (values == null || values.length < 1) {
				return;
			}
			String message = values[0];
			textView.setText(message);
		}

	}

}
